package main

import (
	"database/sql"
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
)

func Login(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	// 从请求中获取用户名和密码
	username := c.PostForm("username")
	password := c.PostForm("password")

	// 查询数据库验证用户信息
	var user User
	err := db.QueryRow("SELECT username, password FROM user WHERE username=?", username).Scan(&user.Username, &user.Password)
	if err != nil {
		if err == sql.ErrNoRows {
			// 用户名不存在，返回错误消息到前端
			c.JSON(http.StatusUnauthorized, gin.H{"error": "用户名或密码错误"})
			return
		}
		log.Println("Error querying user:", err)
		c.AbortWithStatus(http.StatusInternalServerError)
		return
	}

	// 这里仅做示例，实际应用中应该比较哈希后的密码
	if user.Password != password {
		// 密码错误，返回错误消息到前端
		c.JSON(http.StatusUnauthorized, gin.H{"error": "用户名或密码错误"})
		return
	}

	log.Println("Login successful for user:", username)
	// 登录成功，返回其他数据或重定向
	c.Redirect(http.StatusFound, "/index")
}

func Register(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	// 从请求中获取用户名和密码
	username := c.PostForm("username")
	password := c.PostForm("password")

	// 验证用户名是否已存在
	var existingUser User
	err := db.QueryRow("SELECT username, password FROM user WHERE username=?", username).Scan(&existingUser.Username, &existingUser.Password)
	if err == nil {
		// 用户名已存在
		c.HTML(http.StatusConflict, "fail.html", gin.H{"message": "用户名已存在"})
		return
	} else if err != sql.ErrNoRows {
		log.Println("Error querying user:", err)
		c.AbortWithStatus(http.StatusInternalServerError)
		return
	}

	_, err = db.Exec("INSERT INTO user (username, password) VALUES (?, ?)", username, password)
	if err != nil {
		log.Println("Error inserting user:", err)
		c.AbortWithStatus(http.StatusInternalServerError)
		return
	}

	// 注册成功，重定向到登录页面或其他页面
	c.Redirect(http.StatusFound, "/login")
}

func CheckUsername(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	// 从请求中获取用户名
	var requestBody struct {
		Username string `json:"username"`
	}
	if err := c.BindJSON(&requestBody); err != nil {
		log.Println("Error binding JSON:", err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
		return
	}

	// 验证用户名是否已存在
	var existingUser User
	err := db.QueryRow("SELECT username FROM user WHERE username=?", requestBody.Username).Scan(&existingUser.Username)
	if err == nil {
		// 用户名已存在
		c.JSON(http.StatusOK, gin.H{"exists": true})
		return
	} else if err != sql.ErrNoRows {
		log.Println("Error querying user:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"exists": false})
}
func Query(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	sqlStr := "SELECT * FROM student"
	studentSlice, err := MySQLQuery(db, sqlStr) // 添加err变量接收错误
	if err != nil {
		log.Println("Error querying students:", err)
		c.AbortWithStatus(http.StatusInternalServerError)
		return
	}
	titleStr := "学生信息管理"
	c.HTML(http.StatusOK, "index.html", gin.H{
		"student_slice": studentSlice,
		"title":         titleStr,
	})
}

func Add(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	id := c.PostForm("Id")
	name := c.PostForm("Name")
	chinese := c.PostForm("Chinese")
	math := c.PostForm("Math")
	english := c.PostForm("English")

	// 准备SQL插入语句，用于向student表插入新记录。
	stmt, err := db.Prepare("INSERT INTO student (id, name, chinese, math	, english) VALUES (?, ?, ?, ?, ?)")
	if err != nil {
		log.Fatal(err)
	}
	defer stmt.Close() //确保预处理被关闭

	//执行SQL插入操作
	res, err := stmt.Exec(id, name, chinese, math, english)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res.RowsAffected())
	c.Redirect(http.StatusMovedPermanently, "/index")
}

// DeleteOneRow
// 通过HTTP请求来删除数据可的一条消息
func DeleteOneRow(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	var req Student
	if err := c.ShouldBindJSON(&req); err != nil {
		log.Println("Error binding JSON:", err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
		return
	}

	// 插入到回收站表
	result, err := db.Exec("INSERT INTO recycle_bin (id, name, chinese, math, english) SELECT id, name, chinese, math, english FROM student WHERE id = ?", req.Id)
	if err != nil {
		log.Println("Error inserting into recycle_bin:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error"})
		return
	}

	// 从学生表删除
	result, err = db.Exec("DELETE FROM student WHERE id = ?", req.Id)
	if err != nil {
		log.Println("Error deleting student:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error"})
		return
	}

	rowsAffected, err := result.RowsAffected()
	if err != nil {
		log.Println("Error getting rows affected:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error"})
		return
	}

	if rowsAffected == 0 {
		c.JSON(http.StatusNotFound, gin.H{"error": "Student not found"})
		return
	}

	c.Redirect(http.StatusFound, "/index")
}

// 回收站
func ShowRecycleBin(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	sqlStr := "SELECT * FROM recycle_bin"
	deletedstudents, err := MySQLQuery(db, sqlStr) // 添加err变量接收错误
	if err != nil {
		log.Println("Error querying students:", err)
		c.AbortWithStatus(http.StatusInternalServerError)
		return
	}
	titleStr := "回收站"
	c.HTML(http.StatusOK, "recycle_bin.html", gin.H{
		"deleted_students": deletedstudents,
		"title":            titleStr,
	})
}

// 从回收站中恢复
func RestoreStudent(c *gin.Context) {
	id := c.Param("id")
	db := getDBConnection()
	defer db.Close()

	// 启动事务
	tx, err := db.Begin()
	if err != nil {
		log.Println("Error starting transaction:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Error starting transaction"})
		return
	}

	// 从回收站表中获取学生信息
	var student Student
	err = tx.QueryRow("SELECT id, name, chinese, math, english FROM recycle_bin WHERE id = ?", id).Scan(&student.Id, &student.Name, &student.Chinese, &student.Math, &student.English)
	if err != nil {
		log.Println("Error fetching student:", err)
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Error fetching student"})
		return
	}

	// 将学生信息插入到原始表
	_, err = tx.Exec("INSERT INTO student (id, name, chinese, math, english) VALUES (?, ?, ?, ?, ?)", student.Id, student.Name, student.Chinese, student.Math, student.English)
	if err != nil {
		log.Println("Error inserting student:", err)
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Error inserting student"})
		return
	}

	// 从回收站表中删除该学生信息
	_, err = tx.Exec("DELETE FROM recycle_bin WHERE id = ?", id)
	if err != nil {
		log.Println("Error deleting student from recycle_bin:", err)
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Error deleting student from recycle_bin"})
		return
	}

	// 提交事务
	err = tx.Commit()
	if err != nil {
		log.Println("Error committing transaction:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Error committing transaction"})
		return
	}

	c.Redirect(http.StatusFound, "/recycle_bin")
}

// 回收站中永久删除
func PermanentDeleteStudent(c *gin.Context) {
	id := c.Param("id")
	db := getDBConnection()
	defer db.Close()

	// 从回收站表中删除该学生信息
	_, err := db.Exec("DELETE FROM recycle_bin WHERE id = ?", id)
	if err != nil {
		log.Println("Error deleting student from recycle_bin:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Error deleting student from recycle_bin"})
		return
	}

	c.Status(http.StatusOK)
}

// Update
// 更新学生姓名的处理函数
func Update(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	// 从请求中获取信息
	id := c.PostForm("Id")
	newName := c.PostForm("NewName")
	chinese := c.PostForm("Chinese")
	math := c.PostForm("Math")
	english := c.PostForm("English")

	log.Println("Updating student information:", id, newName, chinese, math, english)

	// 准备SQL更新语句
	stmt, err := db.Prepare("UPDATE student SET name = ?, chinese = ?, math = ?, english = ? WHERE id = ?")
	if err != nil {
		log.Fatal(err)
	}
	defer stmt.Close()

	// 执行更新操作
	res, err := stmt.Exec(newName, chinese, math, english, id)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res.RowsAffected())

	// 重定向到首页
	c.Redirect(http.StatusMovedPermanently, "/index")
}

// EditPage
// 显示编辑学生信息页面
func EditPage(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	// 获取URL中的学生ID参数
	studentID := c.Query("id")
	if studentID == "" {
		c.AbortWithStatus(http.StatusBadRequest)
		return
	}

	var student Student

	// 使用db.QueryRow执行SQL查询语句，根据studentID获取学生数据
	err := db.QueryRow("SELECT id, name, chinese, math, english FROM student WHERE id=?", studentID).Scan(&student.Id, &student.Name, &student.Chinese, &student.Math, &student.English)
	if err != nil {
		if err == sql.ErrNoRows {
			c.AbortWithStatus(http.StatusNotFound)
			return
		}
		log.Println("Error querying student:", err)
		c.AbortWithStatus(http.StatusInternalServerError)
		return
	}

	// 传递学生信息给模板 edit.html
	c.HTML(http.StatusOK, "edit.html", gin.H{
		"Id":      student.Id,
		"Name":    student.Name,
		"Chinese": student.Chinese,
		"Math":    student.Math,
		"English": student.English,
	})
}
func SearchByIDHandler(c *gin.Context) {
	db := getDBConnection()
	defer db.Close()

	searchID := c.Query("id")

	if searchID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请输入学生ID进行查询"})
		return
	}

	var student Student
	err := db.QueryRow("SELECT id, name, chinese, math, english FROM student WHERE id=?", searchID).
		Scan(&student.Id, &student.Name, &student.Chinese, &student.Math, &student.English)
	if err != nil {
		if err == sql.ErrNoRows {
			c.JSON(http.StatusNotFound, gin.H{"error": "未找到该学生"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "查询失败，请重试"})
		return
	}

	c.JSON(http.StatusOK, student)
}
